home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / infosrvr / dev / scott / WWW / NextStep / Implementation / HyperManager.m < prev    next >
Text File  |  1993-06-08  |  11KB  |  484 lines

  1. //    HyperText Access method manager Object            HyperManager.m
  2. //    --------------------------------------
  3. //
  4. //    It is the job of a hypermanager to keep track of all the HyperAccess modules
  5. //    which exist, and to pass on to the right one a general request.
  6. //
  7. // History:
  8. //       Oct 90    Written TBL
  9. //
  10. #define NextStep    /* Control HText.h */
  11.  
  12. #define HELP_ENTRY "http://info.cern.ch/hypertext/WWW/NextStep/WorldWideWeb.html"
  13.  
  14. #import "HyperManager.h"
  15.  
  16. #import "HyperText.h"
  17.  
  18. #import "HText.h"
  19. #import "HTUtils.h"
  20. #import "HTParse.h"
  21. #import "HTAccess.h"
  22. #import "HTHistory.h"
  23. #import "HTAlert.h"
  24.  
  25. @implementation HyperManager 
  26.  
  27. #import "WWWPageLayout.h"
  28.  
  29. #define THIS_TEXT  (HyperText *)[[[NXApp mainWindow] contentView] docView]
  30.  
  31. extern char * WWW_nameOfFile(const char * name);    /* In file access */
  32.  
  33. /*    Exported to everyone */
  34.  
  35. int WWW_TraceFlag;    /* Exported to everyone */
  36. char * appDirectory;    /* Name of the directory containing the application */
  37.  
  38. PUBLIC HyperAccess* TheManager;
  39.  
  40. + new
  41. {
  42.     self = [super new];
  43.     accesses = [List new];        // Create and clear list
  44.     TheManager = self;            // For text object sto find 
  45.     return self;
  46. }
  47.  
  48. - traceOn:sender { WWW_TraceFlag = 1; return self;}
  49. - traceOff:sender { WWW_TraceFlag = 0; return self;}
  50.  
  51. - (const char *) name
  52. {
  53.     return "any";
  54. }
  55.  
  56. //            Access Management functions
  57. //
  58.  
  59.  
  60. //    Load an anchor                loadAnchor:
  61. //    --------------
  62. //
  63. //    It checks whether in fact the anchor
  64. //    is already loaded and linked, and that the address string is not null.
  65. //
  66. // On exit:
  67. //    If a duplicate node is found, that anchor is returned
  68. //    If there is no success, nil is returned.
  69. //    Otherwise, the anchor is returned.
  70.  
  71. - loadAnchor:(HTAnchor *)anAnchor Diagnostic:(int)diagnostic
  72. {
  73.  
  74.     HText * HT;
  75.     if (!HTLoadAnchor(anAnchor)) return nil;
  76.  
  77.     //    The node may have become an index: update the existence
  78.     //   state of the panel.
  79.     
  80.     HT = (HText*) HTAnchor_document(HTAnchor_parent(anAnchor));
  81.     if (HTAnchor_isIndex([HT nodeAnchor])) {
  82.     [[keywords window] makeKeyAndOrderFront:self];
  83.     } else {
  84.     [[keywords window] close];
  85. //        [[keywords window] orderOut:self];    @@ bug?
  86.     }
  87.     return self;
  88. }
  89.  
  90. //______________________________________________________________________________
  91.  
  92.  
  93. //    Open or search  by name
  94. //    -----------------------
  95. //
  96. //    @@@ diagnostcics lost
  97. //
  98. - accessName:(const char *)arg
  99.     Diagnostic:(int)diagnostic
  100. {
  101.     return HTLoadAbsolute(arg) ? self : nil;
  102. }
  103.  
  104.  
  105. //    Search with a given diagnostic level
  106. //
  107. //    This involves making a special address string, being the index address
  108. //    with a ? sign followed by a "+" separated list of keywords.
  109. //
  110. - searchDiagnostic:(int)diagnostic
  111. {
  112.  
  113.     HyperText * HT = THIS_TEXT;
  114.     if (!HT) return nil;
  115.     
  116.     HTSearch([keywords stringValueAt:0], [HT nodeAnchor]);
  117.     return self;
  118.  
  119. #ifdef OLD_CODE
  120.     char keys[256];
  121.     char *p, *q, *addr;
  122.     ...
  123.     addr = HTAnchor_address((HTAnchor*)[HT nodeAnchor]);
  124.     if ((p=strchr(addr, '?'))!=0) *p=0;    /* Chop off existing search string */   
  125.     strcat(addr,"?");
  126.     strcpy(keys, [keywords stringValueAt:0]);
  127.     q =HTStrip(keys);            /* Strip leading and trailing */
  128.     for(p=q; *p; p++)
  129.         if (WHITE(*p)) {
  130.         *p='+';            /* Separate with plus signs */
  131.         while (WHITE(p[1])) p++;    /* Skip multiple blanks */
  132.         if (p[1]==0) *p = 0;    /* Chop a single trailing space */
  133.         }
  134.     StrAllocCat(addr, keys);            /* Make combined node name */
  135.     {
  136.         id status = [self accessName:HTStrip(addr) Diagnostic:diagnostic];
  137.         free(addr);
  138.         return status;
  139.     }
  140. #endif
  141.  
  142. }
  143.  
  144. //                N A V I G A T I O N
  145.  
  146.  
  147. //    Relative moves
  148. //    --------------
  149. //
  150. //    These navigate around the web as though it were a tree, from the point of
  151. //    view of the user's browsing order.
  152.  
  153. - back:sender        { HTLoadAnchor(HTHistory_backtrack()); return self; }
  154. - next:sender        { HTLoadAnchor(HTHistory_next); return self; }
  155. - previous:sender    { HTLoadAnchor(HTHistory_previous); return self; }
  156.  
  157.  
  158. //    Go Home
  159. //    -------
  160. //
  161. //    This accesses the default page of text for the user or, failing that,
  162. //    for the system. 
  163. //
  164. static HTParentAnchor * home = NULL;
  165. - goHome:sender
  166. {
  167.     if (!home) home = HTHomeAnchor();
  168.     return HTLoadAnchor((HTAnchor*)home) ? self : nil;
  169. }
  170.  
  171. //    Load Help information
  172. //    ---------------------
  173. //
  174. //
  175. - help:sender
  176. {
  177.     return HTLoadAbsolute(HELP_ENTRY) ? self : nil;
  178. }
  179.  
  180. //    Go to the Blank Page
  181. //    --------------------
  182. //
  183. //
  184. - goToBlank:sender
  185. {
  186.     // return [fileAccess openMy:"blank.html" diagnostic:0];
  187.     return nil;
  188. }
  189.  
  190. //                Application Delegate Methods
  191. //                ============================
  192.  
  193.  
  194. //    On Initialisation, Load Initial File
  195. //    ------------------------------------
  196.  
  197. -appDidInit:sender
  198. {
  199.     if (TRACE) printf("HyperManager: appDidInit\n");
  200.     
  201. //    StrAllocCopy(appDirectory, NXArgv[0]);
  202. //    if (p = strrchr(appDirectory, '/')) p[1]=0;    /* Chop home slash */
  203. //    if (TRACE) printf("WWW: Run from %s\n", appDirectory);
  204.     
  205.     return [self goHome:self];
  206. }
  207.  
  208. //    Accept that we can open files from the workspace
  209.  
  210. - (BOOL)appAcceptsAnotherFile:sender
  211. {
  212.     return YES;
  213. }
  214.  
  215. //    Open file from the Workspace
  216. //
  217. - (int)appOpenFile:(const char *)filename type:(const char *)aType
  218. {
  219.     char * name = WWW_nameOfFile(filename);
  220.     HyperText * HT = [self accessName:name Diagnostic:0];
  221.     free(name);
  222.     return (HT!=0);
  223. }
  224.  
  225. //    Open Temporary file
  226. //
  227. //    @@ Should unlink(2) the file when we have done with it!
  228.  
  229. - (int)appOpenTempFile:(const char *)filename type:(const char *)aType
  230. {
  231.     char * name = WWW_nameOfFile(filename);    /* No host */
  232.     HyperText * HT = [self accessName:name Diagnostic:0];
  233.     free(name);
  234.     return (HT!=0);
  235. }
  236.  
  237.  
  238.  
  239. //        Actions:
  240. //        -------
  241. - search:sender
  242. {
  243.     return [self searchDiagnostic:0];
  244. }
  245.  
  246. - searchRTF:sender
  247. {
  248.     return [self searchDiagnostic:1];
  249. }
  250.  
  251. - searchSGML:sender
  252. {
  253.     return [self searchDiagnostic:2];
  254. }
  255.  
  256.  
  257. //    Direct open buttons:
  258.  
  259. - open:sender
  260. {
  261.     return [self accessName:[openString stringValueAt:0] Diagnostic:0];
  262. }
  263.  
  264. - (HTChildAnchor *) linkToString:sender
  265. {
  266.     return [THIS_TEXT linkSelTo:
  267.             HTAnchor_findAddress([openString stringValueAt:0])
  268.        ];
  269. }
  270.  
  271. - openRTF:sender
  272. {
  273.  return [self accessName:[openString stringValueAt:0] Diagnostic:1];
  274. }
  275.  
  276. - openSGML:sender
  277. {
  278.  return [self accessName:[openString stringValueAt:0] Diagnostic:2];
  279. }
  280.  
  281.  
  282. //    Save a document
  283. //    ---------------
  284. - save:sender
  285. {
  286.     HyperText * HT = THIS_TEXT;
  287.     
  288.     if (YES) {
  289.         HTParentAnchor * anchor = [HT nodeAnchor];
  290.         HTStream * s = HTSaveStream(anchor);
  291.     char * addr;
  292.     if (!s) return nil;
  293.     
  294.     addr = HTAnchor_address((HTAnchor*)anchor); //    The WWW address
  295.         if ([HT writeSGML:s relativeTo:addr])
  296.         [[HT window] setDocEdited:NO];
  297.         free(addr);
  298.     } else {
  299.         HTAlert("Can only save HTML format");
  300.     return nil;
  301.     }
  302. #ifdef NOT_YET
  303.     else if (format==WWW_RICHTEXT) [HT writeRichText:s];
  304.     else if (format==WWW_PLAINTEXT || format==WWW_SOURCE) [HT writeText:s];
  305.     else fprintf(stderr, "HT/File: Unknown format!\n");
  306. #endif    
  307.  
  308.     return self;        /* OK */
  309. }
  310.  
  311. //    Save all hypertexts back
  312. //    -------------------------
  313.  
  314. - saveAll:sender
  315. {
  316.     List * windows = [NXApp windowList];
  317.     id cv;
  318.     int i;
  319.     int n = [windows count];
  320.     
  321.     for(i=0; i<n ; i++){
  322.     Window * w = [windows objectAt:i];
  323.     if (cv=[w contentView])
  324.      if ([cv respondsTo:@selector(docView)])
  325.      if ([w isDocEdited]) {
  326.         HyperText * HT = [[w contentView] docView];
  327.         if ([TheManager saveNode:HT])
  328.             [w setDocEdited: NO];
  329.     }
  330.     }
  331.  
  332.     return self;
  333. }
  334.  
  335.  
  336. //    Close all unedited windows except this one
  337. //    ------------------------------------------
  338. //
  339.  
  340. - closeOthers:sender
  341. {
  342.     Window * thisWindow = [NXApp mainWindow];
  343.     List * windows = [[NXApp windowList] copy];
  344.  
  345.     {
  346.         int i;
  347.     id cv;                    // Content view
  348.     int n = [windows count];
  349.         for(i=0; i<n; i++){
  350.         Window * w = [windows objectAt:i];
  351.         if (w != thisWindow)
  352.         if (cv=[w contentView])
  353.         if ([cv respondsTo:@selector(docView)]) {
  354.             if (![w isDocEdited]) {
  355.             if (TRACE) printf(" Closing window %p\n", (void*)w);
  356.             [w performClose:self];
  357.             }
  358.         }
  359.     }
  360.     [windows free];                /* Free off copy of list */
  361.     return self;
  362.     }
  363. }
  364.  
  365. //    Print Postscript code for the main window
  366. //    -----------------------------------------
  367.  
  368. - print:sender
  369. {
  370.      return [THIS_TEXT printPSCode:sender];
  371. }
  372.  
  373. //    Run the page layout panel
  374. //
  375. - runPagelayout:sender
  376. {
  377.     PageLayout * pl = [WWWPageLayout new];
  378.     [pl runModal];
  379.     return self;
  380. }
  381.  
  382. //    Set the title of the main window
  383. //    --------------------------------
  384.  
  385. - setDocTitle: sender
  386. {
  387.     Window * thisWindow = [NXApp mainWindow];
  388.     [thisWindow setTitle:[titleString stringValueAt:0]];
  389.     [thisWindow setDocEdited:YES];
  390.     return self;
  391. }
  392.  
  393. //    Inspect Link
  394. //    ------------
  395.  
  396. - inspectLink:sender
  397. {
  398.     HTChildAnchor * source = [THIS_TEXT selectedLink];
  399.     HTAnchor * destination;
  400.     if (!source){
  401.         [openString setStringValue: "(No anchor selected in main document.)"
  402.                 at:0];
  403.          return nil;
  404.     }
  405.     {
  406.         char * source_address = HTAnchor_address((HTAnchor*)source);
  407.         [addressString setStringValue: source_address];
  408.     free(source_address);
  409.     }
  410.  
  411.     destination = HTAnchor_followMainLink((HTAnchor*)source);
  412.     if (destination) {
  413.         char * destination_address = HTAnchor_address((HTAnchor*)destination);
  414.         [openString setStringValue: destination_address at:0];
  415.     free(destination_address);
  416.     } else {
  417.     [openString setStringValue: "Anchor not linked."  at:0];
  418.     }
  419.  
  420.     return self;
  421. }
  422.  
  423. //    Copy address of document
  424. //    ------------------------
  425. - copyAddress:sender
  426. {
  427.     char * addr = HTAnchor_address((HTAnchor*)[THIS_TEXT nodeAnchor]);
  428.     [openString setStringValue:addr at:0];
  429.     free(addr);
  430.     return self;
  431. }
  432.  
  433. //        HyperText delegate methods
  434. //        ==========================
  435. //
  436. //    This one has been passed from a window
  437. //    to the hypertext which is its delegate,
  438. //    to the access server module of that hypertext,
  439. //    to this access manager.
  440. //
  441. // When a hypertext window becomes a key window, the search
  442. // panel is turned on or off depending on whether a search can be done,
  443. // and the default address in the "open using full reference" panel
  444. // is set to the address of the current hypertext.
  445. //
  446. - hyperTextDidBecomeMain: sender
  447. {
  448.  
  449.     HTParentAnchor * anchor = [(HText*)sender nodeAnchor];
  450.     char * addr = HTAnchor_address((HTAnchor*)anchor);
  451.     
  452.     HTMainText = sender;        /* Record for HTAccess */
  453.     HTMainAnchor = anchor;
  454.     
  455.     if (HTAnchor_isIndex([sender nodeAnchor])) {
  456.         [[keywords window] makeKeyAndOrderFront:self];
  457.     } else {
  458.         [[keywords window] close];
  459. //        [[keywords window] orderOut:self];    bug?
  460.     }
  461.     [titleString setStringValue: [[sender window] title] at:0];
  462.     [addressString setStringValue: addr];
  463. //  [openString setStringValue: addr at:0];
  464.     free(addr);
  465.     return self;
  466. }
  467.  
  468. //    Panel delegate methods
  469. //
  470. //    The only windows to which this object is a delegate
  471. //    are the open and search panels. When they become key,
  472. //    we ensure that the text is selected.
  473.  
  474. - windowDidBecomeKey:sender
  475. {
  476.     if (sender == [openString window])
  477.         [openString selectTextAt:0];    // Preselect the text
  478.     else if (sender == [keywords window])
  479.         [keywords selectTextAt:0];    // Preselect the text
  480.  
  481.     return self;
  482. }
  483. @end
  484.